package com.yunxin.core.domain.service.order.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.Method;
import cn.hutool.json.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.yunxin.core.domain.external.merchant.MerchantExternalService;
import com.yunxin.core.domain.model.contact.ContactMessageSendTaskDetail;
import com.yunxin.core.domain.model.contact.ContactMessageSendTaskDetailRepository;
import com.yunxin.core.domain.model.contact.ContactMessageTemplateRepository;
import com.yunxin.core.domain.model.order.*;
import com.yunxin.core.domain.service.order.OrderService;
import com.yunxin.core.infra.common.contact.enums.PassiveTriggerEnum;
import com.yunxin.core.infra.persistence.mapper.user.SysUserCoreMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author zero°
 * @since 2023-06-03
 */
@DS("core")
@Service
@RequiredArgsConstructor
@Slf4j
public class OrderServiceImpl implements OrderService {

    private final OrderUserApplyRepository orderUserApplyRepository;

    private final OrderUserApplyDetailRepository orderUserApplyDetailRepository;

    private final OrderUserApplyAllocationRepository orderUserApplyAllocationRepository;

    private final OrderAllocationBelongToAccountRepository orderAllocationBelongToAccountRepository;

    private final OrderUserApplyAllocationStockHandle orderUserApplyAllocationStockHandle;



    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrderUserApply(OrderUserApply userApply, OrderUserApplyDetail orderUserApplyDetail) {
        userApply.setSubmitTime(new Date());
        //保存用户申请订单表
        boolean result = orderUserApplyRepository.saveOrderUserApply(userApply);
        //保存用户申请明细订单表
        orderUserApplyDetailRepository.saveOrderUserApplyDetail(orderUserApplyDetail);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderUserApply(OrderUserApply userApply, OrderUserApplyDetail orderUserApplyDetail) {
        orderUserApplyRepository.updateOrderUserApply(userApply);
        orderUserApplyDetailRepository.updateOrderUserApplyDetail(orderUserApplyDetail);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveOrderUserApplyAllocation(OrderUserApply userApply, OrderUserApplyAllocation orderUserApplyAllocation,
                                             String redisCashField) {
        orderUserApplyRepository.updateOrderUserApply(userApply);
        orderUserApplyAllocationRepository.saveOrderUserApplyAllocation(orderUserApplyAllocation);

        // 新建新的归属账户
        OrderAllocationBelongToAccount allocationBelongToAccount = new OrderAllocationBelongToAccount();
        allocationBelongToAccount.setBelongToStartTime(new Date());
        allocationBelongToAccount.setCreator("init");
        allocationBelongToAccount.setAllocationOrderId(orderUserApplyAllocation.getId());
        allocationBelongToAccount.setOriginalAccountId(orderUserApplyAllocation.getCurrentAccountId());
        allocationBelongToAccount.setCurrentAccountId(orderUserApplyAllocation.getCurrentAccountId());
        orderAllocationBelongToAccountRepository.saveOrderAllocationBelongToAccount(allocationBelongToAccount);
        updateRedis(redisCashField, orderUserApplyAllocation.getProductId());
    }

    /**
     * 根据手机号查询订单详情
     *
     * @param phone
     * @return
     */
    @Override
    public OrderUserApply getIdByUserPhone(String phone) {
        return orderUserApplyRepository.getIdByUserPhone(phone);
    }

    @Override
    public OrderUserApply selectOrderUserApplyAllocationByUserCode(String userCode, Long productId) {
        return orderUserApplyRepository.selectOrderUserApplyAllocationByUserCode(userCode, productId);

    }

    @Override
    public List<OrderUserApply> selectOrderUserApplyAllocationByUserCode1(String userCode, Long productId) {
        return orderUserApplyRepository.selectOrderUserApplyAllocationByUserCode1(userCode, productId);
    }


    /**
     * 更新redis缓存
     *
     * @param redisCashField redisCashField
     * @param productId      productId
     */
    private void updateRedis(String redisCashField, Long productId) {
        if (TransactionSynchronizationManager.isActualTransactionActive()) {
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
                @Override
                public void afterCommit() {
                    // 非兜底产品时再更新
                    if (CharSequenceUtil.isNotBlank(redisCashField)) {
                        orderUserApplyAllocationStockHandle.updateLastOrderProductId(redisCashField, productId);
                    }
                }
            });
        }
    }
}
